#include "genDLList.hpp"

template <class T>
DLList<T>::~DLList(){
    for(DLLNode<T> *tmp; !isEmpty();){
        tmp = head;
        head = head->next;
        head->prev = nullptr;
        delete tmp;
    }
}

template <class T>
void DLList<T>::addToTail(const T& el){
    if(tail != nullptr){
        tail = new DLLNode<T>(el, nullptr, tail);
        tail->prev->next = tail;
    }else{
        head = tail = new DLLNode<T>(el);
    }
}

template <class T>
T* DLList<T>::delFromTail(){
    T* el = new T(tail->info);
    if(head == tail){
        if (head != nullptr){
            delete head;
            head = tail = nullptr;
        }else
        {
            el = nullptr;
        }
    }else{
        tail = tail->prev;
        delete tail;
        tail->next = nullptr;
    }
    return el;   
}

template <class T>
void DLList<T>::addToHead(const T& el){
    
    if(tail != nullptr){
        head = new DLLNode<T>(el, head, nullptr);
        head->next->prev = head;
    }else{
        head = tail = new DLLNode<T>(el);
    }
}

template <class T>
T* DLList<T>::delFromHead(){
    T* el = new T(head->info);
    if(head == tail){
        if(tail != nullptr){
            delete head;
            head = tail = nullptr;
        }else
        {
            el = nullptr;
        }
    }else
    {
        DLLNode<T> *tmp = head;
        head = head->next;
        head->prev = nullptr;
        delete tmp;
    }
    
}

template <class T>
void DLList<T>::delNode(const T& el){
    if (head != nullptr)
    {
       if(head == tail && el == tail->info){
           delete head;
           head = tail = nullptr;
       }else if(el == head->info){
           DLLNode<T> *tmp = head;
           head = head->next;
           head->prev = nullptr;
           delete tmp;
       }else{
           DLLNode<T> *tmp;
           for(tmp = head;tmp->info != el && tmp->next != nullptr;tmp = tmp->next);
           if(tmp != nullptr){
               tmp->prev->next = tmp->next;
               tmp->next->prev = tmp->prev;
               delete tmp;
           }
       }
    }
    
}